package com.zzyl.serve.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.common.core.domain.entity.SysUser;
import com.zzyl.common.core.page.TableDataInfo;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.StringUtils;

import com.zzyl.serve.domain.*;
import com.zzyl.serve.dto.NursingTaskDto;
import com.zzyl.serve.dto.TaskDto;
import com.zzyl.serve.mapper.ElderMapper;
import com.zzyl.serve.mapper.NursingElderMapper;
import com.zzyl.serve.mapper.NursingTaskMapper;
import com.zzyl.serve.service.*;
import com.zzyl.serve.util.CreateTaskUtil;
import com.zzyl.serve.util.IDCardUtils;
import com.zzyl.serve.vo.NursingNameVo;
import com.zzyl.serve.vo.NursingPlanVo;
import com.zzyl.serve.vo.NursingProjectPlanVo;
import com.zzyl.serve.vo.NursingTaskVo;
import com.zzyl.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.zzyl.common.utils.PageUtils.startPage;

/**
 * 护理任务Service业务层处理
 *
 * @author howstrong
 * @date 2024-09-27
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class NursingTaskServiceImpl extends ServiceImpl<NursingTaskMapper, NursingTask> implements INursingTaskService {
    private final NursingTaskMapper nursingTaskMapper;
    private final ICheckInService checkInService;
    private final ICheckInConfigService checkInConfigService;
    private final INursingLevelService nursingLevelService;
    private final INursingPlanService nursingPlanService;
    private final INursingElderService nursingElderService;
    private final INursingProjectService nursingProjectService;
    private final ISysUserService sysUserService;
    private final IElderService elderService;
    private final NursingElderMapper nursingElderMapper;
    private final ISysUserService userService;
    private final ElderMapper elderMapper;
    private final CreateTaskUtil createTaskUtil;


    @Override
    public NursingTaskVo selectNursingTaskById(Long id) {
        NursingTask nursingTask = getById(id);
        NursingTaskVo nursingTaskVo = BeanUtil.toBean(nursingTask, NursingTaskVo.class);

        log.info("获取护理等级名称");
        CheckIn checkIn = checkInService.getOne(Wrappers.<CheckIn>lambdaQuery().eq(CheckIn::getElderId, nursingTask.getElderId()));
        nursingTaskVo.setNursingLevelName(checkIn.getNursingLevelName());

        //获取护理员列表
        List<SysUser> sysUsers = nursingElderMapper.selectUserByElderId(nursingTask.getElderId());
        List<String> list = sysUsers.stream().map(sysUser -> sysUser.getNickName()).collect(Collectors.toList());
        nursingTaskVo.setNursingName(list);
        Elder elder = elderMapper.selectById(nursingTask.getElderId());
        nursingTaskVo.setAge(IDCardUtils.getAgeByIdCard(elder.getIdCardNo()));
        nursingTaskVo.setSex(elder.getSex()==0?"女":"男");

        //获取执行人
        if(StringUtils.isNotEmpty(nursingTask.getUpdateBy())){
            SysUser sysUser = userService.selectUserById(Long.valueOf(nursingTask.getUpdateBy()));
            nursingTaskVo.setUpdater(sysUser.getNickName());
        }

        return nursingTaskVo;
    }

    @Override
    public List<NursingTaskVo> selectNursingTaskList(NursingTaskDto dto) {
        return nursingTaskMapper.selectNursingTaskList(dto);
    }

    @Override
    public void createMonthTask(Elder elder) {
        //1.首先老人不能为空
        if (ObjectUtils.isEmpty(elder)) {
            return;
        }
        //获取入住信息
        CheckIn checkIn = checkInService.getOne(Wrappers.<CheckIn>lambdaQuery().eq(CheckIn::getElderId, elder.getId()));
        if (ObjectUtils.isEmpty(checkIn)) {
            return;
        }
        //获取入住及入住配置信息
        CheckInConfig checkInConfig = checkInConfigService.getOne(Wrappers.<CheckInConfig>lambdaQuery().eq(CheckInConfig::getCheckInId, checkIn.getId()));
        if (ObjectUtils.isEmpty(checkInConfig)) {
            return;
        }
        //4.根据入住表的费用开始时间和结束时间,来判断是月任务还是周任务,还是日任务
        //开始时间
        LocalDateTime startTime = LocalDateTime.now();
        if (checkInConfig.getFeeStartDate().toLocalDate().isEqual(LocalDate.now())) {
            startTime = checkInConfig.getFeeStartDate(); // 当天开始
        }

        //护理等级
        NursingLevel nursingLevel = nursingLevelService.selectNursingLevelById(checkInConfig.getNursingLevelId());
        //护理计划
        NursingPlanVo nursingPlanVo = nursingPlanService.selectNursingPlanById(nursingLevel.getLplanId());
        //查询老人对应的护理员列表
        List<NursingElder> nursingElderList = nursingElderService.list(Wrappers.<NursingElder>lambdaQuery().eq(NursingElder::getElderId, elder.getId()));
        String nursingIds;
        if (CollUtil.isNotEmpty(nursingElderList)) {
            List<Long> list = nursingElderList.stream().map(NursingElder::getNursingId).collect(Collectors.toList());
            //多个id用逗号分隔，转换为字符串
            nursingIds = StringUtils.join(list, ",");
        } else {
            nursingIds = "";
        }
        //查询所有的护理项目
        List<NursingProject> nursingProjectList = nursingProjectService.list(Wrappers.<NursingProject>lambdaQuery().eq(NursingProject::getStatus, 1));
        //转换为Map
        Map<Long, String> nursingProjectMap = nursingProjectList.stream().collect(Collectors.toMap(NursingProject::getId, NursingProject::getName));
        //组装护理任务
        List<NursingTask> nursingTasks = new ArrayList<>();

        LocalDateTime finalStartTime = LocalDateTime.now();

        nursingPlanVo.getProjectPlans().forEach(v -> {
            //执行频次
            Integer executeFrequency = v.getExecuteFrequency();
            //执行时间
            String executeTime = v.getExecuteTime();
            LocalTime localTime = LocalTime.parse(executeTime);
            //开始执行时间
            LocalDateTime firstExecutionTime = LocalDateTime.of(finalStartTime.toLocalDate(), localTime);
            // 计算相差天数
            LocalDateTime monthEndTime = LocalDateTime.of(finalStartTime.getYear(), checkInConfig.getFeeStartDate().getMonth(), finalStartTime.toLocalDate().lengthOfMonth(), 23, 59);
            // 间隔天数
            long diffDays = monthEndTime.toLocalDate().toEpochDay() - finalStartTime.toLocalDate().toEpochDay() + 1;
            if (v.getExecuteCycle().equals(0)) {
                // 日
                createTaskUtil.createTaskByDay(firstExecutionTime, diffDays, nursingTasks, executeFrequency, elder, v, nursingIds, nursingProjectMap);
            } else if (v.getExecuteCycle().equals(1)) {
                // 周
                createTaskUtil.createTaskByWeek(firstExecutionTime, diffDays, nursingTasks, executeFrequency, elder, v, monthEndTime, nursingIds, nursingProjectMap);
            } else {
                // 月
                createTaskUtil.createTaskByMonth(firstExecutionTime, monthEndTime, nursingTasks, executeFrequency, elder, v, nursingIds, nursingProjectMap);
            }
        });

        if (CollUtil.isEmpty(nursingTasks)) {
            return;
        }
        saveBatch(nursingTasks);
    }
}
